package org.jeecg.modules.demo.lydasystem.util;

import lombok.extern.slf4j.Slf4j;

import javax.mail.*;
import javax.mail.internet.*;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 多种告警通知器实现
 */
@Slf4j
public class AlarmNotifiers {

    /**
     * 控制台告警通知器
     */
    public static class ConsoleAlarmNotifier implements HJ212DataReceiver.AlarmNotifier {
        @Override
        public void sendAlarm(String alarmMessage) {
            System.err.println("🚨 [控制台告警] " + alarmMessage);
            log.warn(alarmMessage);
        }
    }

    /**
     * 日志文件告警通知器
     */
    public static class FileAlarmNotifier implements HJ212DataReceiver.AlarmNotifier {
        private String logFilePath;

        public FileAlarmNotifier(String logFilePath) {
            this.logFilePath = logFilePath;
        }

        @Override
        public void sendAlarm(String alarmMessage) {
            try (FileWriter fw = new FileWriter(logFilePath, true);
                 PrintWriter pw = new PrintWriter(fw)) {
                String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
                pw.println("[" + timestamp + "] 告警: " + alarmMessage);
            } catch (IOException e) {
                System.err.println("写入告警日志失败: " + e.getMessage());
            }
        }
    }

    /**
     * 邮件告警通知器
     */
    public static class EmailAlarmNotifier implements HJ212DataReceiver.AlarmNotifier {
        private String smtpHost;
        private String smtpPort;
        private String username;
        private String password;
        private String fromEmail;
        private String toEmail;

        public EmailAlarmNotifier(String smtpHost, String smtpPort, String username,
                                  String password, String fromEmail, String toEmail) {
            this.smtpHost = smtpHost;
            this.smtpPort = smtpPort;
            this.username = username;
            this.password = password;
            this.fromEmail = fromEmail;
            this.toEmail = toEmail;
        }

        @Override
        public void sendAlarm(String alarmMessage) {
            try {
                Properties props = new Properties();
                props.put("mail.smtp.host", smtpHost);
                props.put("mail.smtp.port", smtpPort);
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.starttls.enable", "true");

                Session session = Session.getInstance(props, new Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(fromEmail));
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
                message.setSubject("🚨 水质监测系统告警");
                message.setText("告警时间: " + new java.util.Date() + "\n\n" + alarmMessage);

                Transport.send(message);
                System.out.println("告警邮件已发送");
            } catch (Exception e) {
                System.err.println("发送告警邮件失败: " + e.getMessage());
            }
        }
    }

    /**
     * 复合告警通知器（同时使用多种通知方式）
     */
    public static class CompositeAlarmNotifier implements HJ212DataReceiver.AlarmNotifier {
        private List<HJ212DataReceiver.AlarmNotifier> notifiers = new ArrayList<>();

        public void addNotifier(HJ212DataReceiver.AlarmNotifier notifier) {
            notifiers.add(notifier);
        }

        @Override
        public void sendAlarm(String alarmMessage) {
            for (HJ212DataReceiver.AlarmNotifier notifier : notifiers) {
                try {
                    notifier.sendAlarm(alarmMessage);
                } catch (Exception e) {
                    System.err.println("告警通知器执行失败: " + e.getMessage());
                }
            }
        }
    }
}
